import RemoveList from '@/utils/RemoveList';
import CanvasUtils from '@/utils/CanvasUtils';
import { SpotI } from '@/utils/CanvasUtils/CanvasType';
import Paint, { ElementBaseEventMap, ElementBaseEventType } from '@/paint/Paint';

export default class BaseElement {

	/** 画板 */
	protected paint: Paint;

	/** 事件列表 */
	protected eventList: RemoveList = new RemoveList();

	/** 处于悬停 */
	protected onHover: boolean = false;

	/** 渲染级别 */
	public zIndex: number = 0;

	/** 处于悬停 */
	public get OnHover(): boolean {
		return this.onHover;
	}

	/** 渲染级别 */
	public get Z_Index() {
		return this.zIndex;
	}

	/**
	 * 构造函数
	 * @param paint 画板类
	 */
	public constructor(paint: Paint) {
		this.paint = paint;
	}

	/** 移除 */
	public Remove() {
		this.paint.RemoveElement(this);
	}

	/**
	 * 绘制 override
	 * @param canvas 画板类
	 */
	public Draw(canvas: CanvasUtils): void {
		throw new Error("Method should extends.");
	}

	/**
	 * 是否位于区域内 override
	 * @param spot 被判断的点
	 */
	public OnRange(spot: SpotI): boolean {
		throw new Error("Method should extends.");
	}

	/** 移除所有事件 */
	public ClearEvent(): void {
		this.eventList.Clear();
	}

	/**
	 * 添加事件
	 * @param type 事件类型
	 * @param input 事件参数
	 */
	public AddEvent<T extends ElementBaseEventType>(type: T, input: ElementBaseEventMap[T]): () => void;
	public AddEvent(type: ElementBaseEventType, input: any): any {
		const { paint } = this;
		if (type === "click") {
			return this.eventList.Add(paint.AddEvent(this, type, (spot: SpotI) => {
				if (this.OnRange(spot)) {
					input(spot);
				}
			}));
		}
		else if (type === "hover") {
			return this.eventList.Add(paint.AddEvent(this, "move", (spot: SpotI) => {
				const hover = this.OnRange(spot);
				if (hover != this.onHover) {
					this.onHover = hover;
					input(hover, spot);
				}
			}));
		}
		else if (type === "move") {
			return this.eventList.Add(paint.AddEvent(this, type, (spot: SpotI) => {
				if (this.OnRange(spot)) {
					input(spot);
				}
			}));
		}
	}

}
